<?php
// +----------------------------------------------------------------------
// | APP版本
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 微尘 <yicmf@qq.com>
// +----------------------------------------------------------------------
namespace app\event\app;

use app\common\event\Base;
use app\event\ucenter\User as UserEvent;
use app\model\app\JdOrder as JdOrderModel;
use app\model\app\JdGood as JdGoodModel;
use app\model\ucenter\User as UserModel;
use app\model\ucenter\UserMoneyLog as UserMoneyLogModel;
use app\model\ucenter\UserTask as UserTaskModel;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\helper\Str;

class Jd extends Base
{


    private $json_param_key = "360buy_param_json";

    public $appKey = '7f6bdd2f331fbd883d680f25a8df8fc5';

    public $appSecret = 'd5184b5924d94337a68360d546c57a62';
//
//    public $appKey = '40a56ba72ec5ca2db05610b032d40cd2';
//
//    public $appSecret = 'a327d092032e4945a3dc86ff8554a6c6';

    protected function generateSign($params)
    {
        ksort($params);
        $stringToBeSigned = $this->appSecret;
        foreach ($params as $k => $v) {
//            if(!is_string($v) && is_array($v)){
            if ($this->json_param_key == $k) {
                $stringToBeSigned .= "$k" . json_encode($v, JSON_UNESCAPED_SLASHES);
            } else {
                $stringToBeSigned .= "$k$v";
            }

        }
        unset($k, $v);
        $stringToBeSigned .= $this->appSecret;

        return strtoupper(md5($stringToBeSigned));
    }

    private function getStandardOffsetUTC($timezone)
    {
        if ($timezone == 'UTC') {
            return '+0000';
        } else {
            $timezone = new \DateTimeZone($timezone);
            $transitions = array_slice($timezone->getTransitions(), -3, null, true);

            foreach (array_reverse($transitions, true) as $transition) {
                if ($transition['isdst'] == 1) {
                    continue;
                }

                return sprintf('%+03d%02u', $transition['offset'] / 3600, abs($transition['offset']) % 3600 / 60);
            }

            return false;
        }
    }

    public $connectTimeout = 0;

    public $readTimeout = 0;
    public $domain = 'https://api.jd.com/routerjson';//

    public function curl($serverUrl, $sysParams)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($this->readTimeout) {
            curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
        }
        if ($this->connectTimeout) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
        }
        //https 请求
        if (strlen($serverUrl) > 5 && strtolower(substr($serverUrl, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        // 此处修改暂时为了保证顺利上传，直接base64编码文件流的方式来上传。所以$postMultipart 依然为false
        //获取业务参数
        $apiParams = $sysParams[$this->json_param_key];

        /* 1)全部使用POST方式，multi和simple。
        2)$postMultipart 暂时没有用，字节流拼接成串的方式上传，所以先去掉
        */
        curl_setopt($ch, CURLOPT_POST, true);

        // 需要把系统参数依然使用url方式传递
        $requestUrl = $serverUrl . "?";
        foreach ($sysParams as $sysParamKey => $sysParamValue) {
            if ($sysParamKey != $this->json_param_key) {
                $requestUrl .= "$sysParamKey=" . urlencode($sysParamValue) . "&";
            }
        }

        // 去掉末尾的 "&"
        curl_setopt($ch, CURLOPT_URL, substr($requestUrl, 0, -1));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->json_param_key . "=" . urlencode(json_encode($apiParams, JSON_UNESCAPED_SLASHES)));

        $reponse = curl_exec($ch);
        if (curl_errno($ch)) {
            throw new Exception(curl_error($ch), 0);
        } else {
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode) {
                throw new Exception($reponse, $httpStatusCode);
            }
        }
        curl_close($ch);
        return $reponse;
    }

    protected function _request($param, $method)
    {
        //组装系统参数
        $sysParams['app_key'] = $this->appKey;
        $sysParams['format'] = 'json';
        $sysParams['sign_method'] = 'md5';
        $sysParams['v'] = '1.0';
        $sysParams['method'] = $method;
        $sysParams['timestamp'] = date("Y-m-d H:i:s") . '.000' . $this->getStandardOffsetUTC(date_default_timezone_get());;
        $sysParams[$this->json_param_key] = $param;

        $json = str_replace('.', '_', $method) . '_responce';
//        $sysParams[$this->json_param_key] = json_encode($sysParams[$this->json_param_key]);
        //签名
        $sysParams['sign'] = $this->generateSign($sysParams);
        $re = $this->curl($this->domain, $sysParams);
        $res = json_decode($re, true);
        if (isset($res['error_response'])) {
            throw new Exception($res['error_response']['zh_desc'], $res['error_response']['code']);
        }
        $res = $res[$json];
        if ($res['code'] == 0) {
            return isset($res['queryResult']) ? json_decode($res['queryResult'], true) : (isset($res['getResult']) ? json_decode($res['getResult'], true) : false);
        } else {
            throw new Exception('系统故障');
        }
    }

    public function getOrder($type, $time, $old_time = 1800)
    {

        try {
            $param['orderReq']['pageIndex'] = 1;
            $param['orderReq']['pageSize'] = 100;
            $param['orderReq']['type'] = $type;
            $param['orderReq']['startTime'] = time_format($time - $old_time, 'Y-m-d H:i:s');
            $param['orderReq']['endTime'] = time_format($time, 'Y-m-d H:i:s');
            $res = $this->_request($param, 'jd.union.open.order.row.query');
            if ($res['code'] != 200) {
                throw new Exception($res['message']);
            }
            if (isset($res['data'])) {
                foreach ($res['data'] as $trades) {
                    $this->_sysnOrder($trades);
                }
            }
            $result = ['code' => 0, 'data' => $res];
        } catch (\Exception $e) {
            // 回滚事务
            $result = ['code' => 1, 'message' => $e->getMessage()];
        }
        return $result;


    }

    public function getLike($type, $time, $old_time = 1800)
    {
        $param['goodsReq']['eliteId'] = 3;
        $param['goodsReq']['pageIndex'] = 1;
        $param['goodsReq']['pageSize'] = 10;
        $param['goodsReq']['positionId'] = '3101167921';

        $res = $this->_request($param, 'jd.union.open.goods.material.query');

        if ($res['code'] == 200) {

            return $res;
        } else {
            throw new Exception($res['message']);
        }

    }

    public function getPromotio1n()
    {
        $param['promotionCodeReq']['materialId'] = 'https://u.jd.com/bDvDMgT';
        $param['promotionCodeReq']['positionId'] = '3101167921';
        $param['promotionCodeReq']['siteId'] = '4101357054';
        $param['promotionCodeReq']['sceneId'] = 1;
//        $param['promotionCodeReq']['positionId'] = '2035795074_4101354001_3101164733';

        $res = $this->_request($param, 'jd.union.open.promotion.common.get');

        dump($res);
        exit();
        if ($res['code'] == 200) {

            return $res;
        } else {
            throw new Exception($res['message']);
        }

    }

    /**
     * 链接解析
     * @param $content
     * @param $user
     * @return void
     */
    public function parseContent($content, $user, $from)
    {
        try {
            if (!$user) {
                throw new Exception('请先登录');
            }
            $this->_user = $user;
            if ($from == 'search') {
                $param['promotionCodeReq']['materialId'] = $content;
                $info = JdGoodModel::where('item_id', $content)->where('user_id', $user['id'])->find();
                if (!$info) {
                    throw new Exception('数据丢失');
                }
            } elseif ($from == 'all_back') {
                $param['promotionCodeReq']['materialId'] = $content;
            } else {
                $search = $this->goodSearch($content);
                if (!isset($search['data']) || count($search['data']) == 0) {
                    throw new Exception('商品暂无返利');
                }
                $good = [];
                foreach ($search['data'][0] as $index_g => $item) {
                    $good[Str::snake($index_g)] = $item;
                }
                $info = JdGoodModel::where('item_id', $good['item_id'])->where('keyword', $content)->where('user_id', $user['id'])->find();
                if (!$info) {
                    $good['keyword'] = $content;
                    $good['user_id'] = $user['id'];
                    $info = JdGoodModel::create($good);
                }

                $param['promotionCodeReq']['materialId'] = $search['data'][0]['materialUrl'];
            }

//            $param['promotionCodeReq']['materialId'] = $search['data'][0]['materialUrl'];
//            $param['promotionCodeReq']['positionId'] = '3101167921';
//            $param['promotionCodeReq']['siteId'] = '4101357054';
//            $param['promotionCodeReq']['subUnionId'] = $user['username'] . '_' . $user['id'];
//            $param['promotionCodeReq']['sceneId'] = 1;
//            $param['promotionCodeReq']['proType'] = 5;
//            $param['promotionCodeReq']['command'] = 1;
//            $res = $this->_request($param, 'jd.union.open.promotion.common.get');
            $param['promotionCodeReq']['positionId'] = '3101167921';
            $param['promotionCodeReq']['siteId'] = '4101357054';
            $param['promotionCodeReq']['subUnionId'] = $user['username'] . '_' . $user['id'];
            $param['promotionCodeReq']['sceneId'] = 1;
//            $param['promotionCodeReq']['proType'] = 5;
            $param['promotionCodeReq']['chainType'] = 3;
            $res = $this->_request($param, 'jd.union.open.promotion.bysubunionid.get');

            if ($res['code'] != 200) {
                throw new Exception($res['message']);
            }
            if ($from == 'all_back') {
                $result['code'] = 0;
                $result['data']['share'] = $res['data'];
            } else {
                $info['click_url'] = $res['data']['clickURL'];
                $info['short_url'] = $res['data']['shortURL'];
                $info->save();
                $result['code'] = 0;
                $result['data']['share'] = Rebate::formatGood($info, 'jd');
            }

            $result['data']['channel'] = 'jd';
            $result['message'] = '获取成功';
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $result = ['code' => 1, 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()];
        }
        return $result;
    }

    /**
     * 关键词搜索
     * @param $content
     * @param $user
     * @return void
     */
    public function searchByKeyword($content, $user, $page = 1)
    {
        try {
            if (!$user) {
                throw new Exception('请先登录');
            }
            $this->_user = $user;

            $search = $this->goodSearch($content);
            if (isset($search['data']) && count($search['data']) == 0) {
                throw new Exception('商品暂无返利');
            }
            $goods = [];
            foreach ($search['data'] as $item) {
                $good = [];
                foreach ($item as $index_g => $good_value) {
                    $good[Str::snake($index_g)] = $good_value;
                }
                $good['keyword'] = $content;
                $good['user_id'] = $user['id'];
                $has = JdGoodModel::where('user_id', $user['id'])->where('keyword', $content)
                    ->where('spuid', $good['spuid'])
                    ->find();
                // 查询近期
                if (!$has) {
                    $goods[] = JdGoodModel::create($good)->toArray();
                } else {
                    $goods[] = $has->toArray();
                }
            }
            $result['data'] = $goods;
            $result['code'] = 0;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $result = ['code' => 1, 'message' => $e->getMessage()];
        }
        return $result;
    }

    /**
     * 产品搜索 jd.union.open.goods.query
     * @return void
     * @throws Exception
     */
    public function goodSearch($keyword, $page = 1)
    {
        $param['goodsReqDTO']['pageIndex'] = $page;
        $param['goodsReqDTO']['pageSize'] = 30;
        $param['goodsReqDTO']['keyword'] = $keyword;
        $param['goodsReqDTO']['positionId'] = '3101167921';
        $param['goodsReqDTO']['siteId'] = '4101357054';
        $param['goodsReqDTO']['ip'] = $this->request->ip();
        return $this->_request($param, 'jd.union.open.goods.query');
    }

    public function getPromotion($type, $time, $old_time = 1800)
    {
        $param['promotionCodeReq']['positionId'] = '3101167921';
        $param['promotionCodeReq']['materialId'] = 'jingfen.jd.com/detail/3nWU4vOI0UDbZ5xBQ26V001D_3cvPR81Ja0sSwQiQ12.html';

        $res = $this->_request($param, 'jd.union.open.promotion.bysubunionid.get');

        if ($res['code'] == 200) {

            return $res;
        } else {
            throw new Exception($res['message']);
        }

    }

    public function getJingfen($type, $time, $old_time = 1800)
    {
        $param['goodsReq']['eliteId'] = 12254;
        $param['goodsReq']['pageIndex'] = 1;
        $param['goodsReq']['pageSize'] = 10;
        $param['goodsReq']['pid'] = '2035795074_0_3101167921';

        $res = $this->_request($param, 'jd.union.open.goods.jingfen.query', 'jd_union_open_order_row_query_responce');

        if ($res['code'] == 200) {

            return $res;
        } else {
            throw new Exception($res['message']);
        }

    }


    private function _sysnOrder($trades)
    {
        $trade = [];
        foreach ($trades as $index_g => $item) {
            if ($index_g == 'id') {
                $trade['jd_sn'] = $item;
            } else {
                $trade[Str::snake($index_g)] = $item;
            }
        }
        if (!empty($trade['item_id']) && false !== strpos($trade['item_id'], '_')) {
            $trade['item_id'] = explode('_', $trade['item_id'])[1];
        }
        if (!empty($trade['finish_time'])) {
            $trade['receive_time'] = $trade['finish_time'];
        }
        $jd = JdOrderModel::where('order_id', $trade['order_id'])->find();

        if (!$jd) {
            $jd = JdOrderModel::create($trade);
            if (!empty($jd['sub_union_id'])) {
                $user = UserModel::where('id', explode('_', $jd['sub_union_id'])[1])->find();
                if ($user) {
                    $jd['user_id'] = $user['id'];
                    $jd->save();
                    $userTask = $this->_bindTask($jd, $user);
                    $this->_payFee($userTask, $jd);
                }
            }
        } else {

            if ($trade['modify_time'] != $jd['modify_time']) {
                $jd->save($trade);
                // 退款订单
//            $jd['express_status'] = $trade['express_status'];
//            $jd['valid_code'] = $trade['valid_code'];//sku维度的有效码（-1：未知,2.无效-拆单,3.无效-取消,4.无效-京东帮帮主订单,
                //5.无效-账号异常,6.无效-赠品类目不返佣,7.无效-校园订单,8.无效-企业订单,9.无效-团购订单,
                //11.无效-乡村推广员下单,13.无效-违规订单,14.无效-来源与备案网址不符,15.待付款,
                //16.已付款,17.已完成（购买用户确认收货）,20.无效-此复购订单对应的首购订单无效,
                //21.无效-云店订单22.无效-PLUS会员佣金比例为0,23.无效-支付有礼,24.已付定金,25.
                // 违规订单-流量劫持,26. 违规订单-流量异常,27. 违规订单-违反京东平台规则,28.
                // 违规订单-多笔交易异常,29.无效-跨屏跨店,30.无效-累计件数超出类目上限,
                //29.无效-跨屏跨店,30.无效-累计件数超出类目上限,31.无效-黑名单sku
                // refund_tag维权标签，0 含义为非维权 1 含义为维权订单 维权标签，0 含义为非维权 1 含义为维权订单
//            $jd->save();
                if ($jd['user_id']) {
                    $user = UserModel::where('id', $jd['user_id'])->find();
                    if ($user) {
                        $userTask = UserTaskModel::where('user_id', $user['id'])
                            ->where('task_id', 11)
                            ->where('task_type', 23)
                            ->where('relation_id', $jd['id'])
                            ->find();
                        if ($userTask) {
                            $userTask['step'] = $jd['valid_code'];
                            $userTask['submit_info'] = $jd->toArray();
                            $userTask->save();
                            $this->_payFee($userTask, $jd);
                        }
                    }
                }
            }

        }
    }

    public function test1()
    {

        $domain = 'https://api.jd.com/routerjson';
        //组装系统参数
        $sysParams['app_key'] = $this->appKey;
        $sysParams['format'] = 'json';
        $sysParams['sign_method'] = 'md5';
        $sysParams['v'] = '1.0';
        $sysParams['method'] = 'jd.union.open.goods.jingfen.query';
//        $sysParams['timestamp'] = date("Y-m-d H:i:s").'.000'.$this->getStandardOffsetUTC(date_default_timezone_get());;
        $sysParams['timestamp'] = date("Y-m-d H:i:s");

        //$sysParams["access_token"] = $access_token;

        $sysParams[$this->json_param_key]['goodsReq']['eliteId'] = 1;
//        $sysParams[$this->json_param_key]['goodsReqDTO']['keyword'] = '鞋子';
//        $sysParams[$this->json_param_key]['orderReq']['startTime'] = '2024-12-09 16:11:01';
//        $sysParams[$this->json_param_key]['orderReq']['startTime'] = '2024-12-09+16:51:01';
//        $sysParams[$this->json_param_key] = json_encode($sysParams[$this->json_param_key]);
        //签名
        $sysParams["sign"] = $this->generateSign($sysParams);


        $re = $this->curl($domain, $sysParams);
        dump(json_decode($re, true));
        dump($sysParams);
        exit();


    }


    /**
     * 补单
     * @param $order
     * @param $user
     * @return array
     */
    public function supplement($order, $user)
    {
        try {
            if (!$order) {
                throw new Exception('订单异常');
            }
            $order['user_id'] = $user['id'];
            $order->save();
            $userTask = $this->_bindTask($order, $user);
            $this->_payFee($userTask, $order);
            $result['code'] = 0;
        } catch (\Exception $e) {
            // 回滚事务
            $result = ['code' => 1, 'message' => $e->getMessage()];
        }
        return $result;
    }

    private function _bindTask($order, $user)
    {
        // 新增任务
        $userTask['task_id'] = 11;
        $userTask['relation_id'] = $order['id'];
        $userTask['task_type'] = 23;
        $userTask['user_id'] = $user['id'];
        $userTask['agent_id'] = $user['agent_id'];
        $userTask['title'] = $order['sku_name'];
        $userTask['logo'] = isset($order['goods_info']['imageUrl']) ? $order['goods_info']['imageUrl'] : '';
        $userTask['money'] = $order['estimate_cos_price'];
        if ($order['estimate_fee'] <= 2.1) {
            // 最多两单
//            $count = JdOrderModel::where('user_id', $user['id'])->count();
//            if ($count<=2)
//            {
//                $userTask['commission'] = $order['money'];;
//            }else{
//            $userTask['commission'] = $order['estimate_fee'];
            if ($order['estimate_fee'] < 2) {
                $userTask['commission'] = $order['money'];
            } else {
                $userTask['commission'] = 2;
            }
//            }
//            $userTask['commission'] = $order['money'];
        } else {
            $userTask['commission'] = $order['estimate_fee'];
        }

        $userTask['task_no'] = $order['order_id'];
//        $userTask['end_time'] = time() + 30 * 86400;
        $userTask['step'] = $order['valid_code'];
        $userTask['submit_info'] = $order->toArray();
        $userTask['status'] = 1;
        $userTask = UserTaskModel::create($userTask);
        if (!$userTask) {
            throw new Exception('系统故障');
        }
        return $userTask;
    }


    protected function _payFee($userTask, $order)
    {

        //sku维度的有效码（-1：未知,2.无效-拆单,3.无效-取消,4.无效-京东帮帮主订单,
        //5.无效-账号异常,6.无效-赠品类目不返佣,7.无效-校园订单,8.无效-企业订单,9.无效-团购订单,
        //11.无效-乡村推广员下单,13.无效-违规订单,14.无效-来源与备案网址不符,15.待付款,
        //16.已付款,17.已完成（购买用户确认收货）,20.无效-此复购订单对应的首购订单无效,
        //21.无效-云店订单22.无效-PLUS会员佣金比例为0,23.无效-支付有礼,24.已付定金,25.
        // 违规订单-流量劫持,26. 违规订单-流量异常,27. 违规订单-违反京东平台规则,28.
        // 违规订单-多笔交易异常,29.无效-跨屏跨店,30.无效-累计件数超出类目上限,
        //29.无效-跨屏跨店,30.无效-累计件数超出类目上限,31.无效-黑名单sku

        if (in_array($userTask['step'], [-1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 14, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31])) {
            // 订单失效。
            $userTask['status'] = 3;
        } elseif ($userTask['step'] == 15) {
            $userTask['status'] = 0;
        } elseif ($userTask['step'] == 16) {
            $userTask['status'] = 1;
        } elseif ($userTask['step'] == 17) {
            $userTask['status'] = 2;
            //actual_fee
            // 发放佣金
            if ($order['actual_fee'] <= 2) {
                // 最多两单
                $count = JdOrderModel::where('user_id', $userTask['user_id'])->count();
                if ($count <= 2) {
                    if ($order['actual_fee'] < 2) {
                        $userTask['commission'] = $order['money'];
                    } else {
                        $userTask['commission'] = 2;
                    }
                } else {
                    $userTask['commission'] = $order['estimate_fee'];
                }
            } else {
                $userTask['commission'] = $order['actual_fee'];
            }
            $log = UserMoneyLogModel::where('user_id', $userTask['user_id'])->where('type', 39)
                ->where('order_id', $userTask['task_no'])
                ->where('channel', 'jd')->find();
            if (!$log && !empty($userTask['commission']) && $userTask['commission'] > 0) {
                $user = UserModel::where('id', $userTask['user_id'])->find();
                UserEvent::exhibitionIncome($user, $userTask['commission'], $userTask['title'], 39, $user['id'], $userTask['task_no'], 0, 'jd', 11);
            }
        } else {
            $userTask['status'] = 4;
        }

        $userTask->save();
        if ($userTask['status'] == 3 || $userTask['status'] == 4) {
            // 失败订单，查询是否扣款
            $log = UserMoneyLogModel::where('user_id', $userTask['user_id'])->where('type', 39)
                ->where('order_id', $userTask['task_no'])
                ->where('channel', 'jd')
                ->where('is_eversal', 0)
                ->find();
            if ($log) {
                $user = UserModel::where('id', $userTask['user_id'])->find();
                UserEvent::exhibitionIncomeBack($user, 39, '电商返利因退款或退货返佣取消', $user['id'], $userTask['task_no'], 'jd', 11);
            }
        }
    }

}
